package GUI;

import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Vector;
import java.util.concurrent.locks.ReentrantLock;


import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

import Algorthim.*;

import phylogenetictree.PhylogeneticTree;
import searchTree.searchTreeNode;


public class JMAF {
	private JFrame page = new JFrame(" Maximum Agreement Forest Finder for phylogenetic Tree ");
	private JTextField treeOneFLD = new JTextField();
	private JTextField treeTwoFLD = new JTextField();
	private JTextField kFLD = new JTextField();
	private JTextField TBRFLD = new JTextField();
	private JTextField treeSizeFLD = new JTextField();
	private JComboBox solveOptionsCB = new JComboBox(new String[]{"First Soultion","Best Soultion","All Soultions"});
	private JComboBox ConcurrencyOptionsCB = new JComboBox(new String[]{"None","Thread Spaming","heavy Weight","singleQuque"});
	private JFileChooser fc = new JFileChooser("trees");
	
	final JList list = new JList();
	
	private String treeOnePath; 
	private PhylogeneticTree treeOne;
	
	private String treeTwoPath;
	private PhylogeneticTree treeTwo;
	
	ArrayList<searchTreeNode> Result;
	
//	private phylogeneticTree MAF;
	
	public static void main(String[] input)
	{
		JMAF program = new JMAF();
		program.runProgram();
	}
	
	public void runProgram()
	{
		JPanel soultions = new JPanel();
		JPanel input = new JPanel();
		
		JSplitPane center = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
		center.setDividerLocation(800); // adjust to find nice value
		
		//create and set up buttons
		
		/// tree one buttons
		JButton loadTreeOneBTN = new JButton("Load Tree");
		loadTreeOneBTN.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				int returnVal = fc.showOpenDialog(new JPanel());
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = fc.getSelectedFile();
		            treeOnePath = file.getAbsolutePath();
		            try {
						treeOne = new PhylogeneticTree(treeOnePath);
					} catch (IOException e1) {
						JFrame dialog = new JFrame("ERROR");
						dialog.add(new JLabel("File Not Foundn ",JLabel.CENTER));
						dialog.setVisible(true);
					}
		            treeOneFLD.setText(file.getName());
				}
			}
		});
		
		JButton saveTreeOneBtn = new JButton("Save Tree One");
		saveTreeOneBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnVal = fc.showSaveDialog(new JPanel());
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = fc.getSelectedFile();
		            writeFile(treeOne.toCommaSeperatedFile(),file);
				}
			}
		});
		
		/// tree Two buttons
		JButton loadTreeTwoBTN = new JButton("Load Tree");
		loadTreeTwoBTN.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				int returnVal = fc.showOpenDialog(new JPanel());
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = fc.getSelectedFile();
		            treeTwoPath = file.getAbsolutePath();
		            try {
						treeTwo = new PhylogeneticTree(treeTwoPath);
					} catch (IOException e1) {
						JFrame dialog = new JFrame("ERROR");
						dialog.add(new JLabel("File Not Foundn ",JLabel.CENTER));
						dialog.setVisible(true);
					}
		            treeTwoFLD.setText(file.getName());
				}
			}
		});
		
		JButton saveTreeTwoBtn = new JButton("Save Tree Two");
		saveTreeTwoBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnVal = fc.showSaveDialog(new JPanel());
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = fc.getSelectedFile();
		            writeFile(treeTwo.toCommaSeperatedFile(),file);
				}
			}
		});
		
		JButton randomTreeBTN = new JButton("Create Random Tree");
		randomTreeBTN.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent e) {
				treeOne = new PhylogeneticTree(Integer.parseInt(treeSizeFLD.getText()));
				treeOneFLD.setText("Random Tree");
			}
		});
		
		JButton mutateTreeBTN = new JButton("mutate Tree One");
		mutateTreeBTN.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent arg0) {
				treeTwo = treeOne.createMutant(Integer.valueOf(TBRFLD.getText()));
				treeTwoFLD.setText("mutant");
			}
		});
		
		JButton findMAFBTN = new JButton("Find MAF");
		findMAFBTN.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String item = (String)ConcurrencyOptionsCB.getSelectedItem();
//				ArrayList<searchTreeNode> Result = null;
				
				Algorithim program = null;
				if(item.equals("None"))
				{
					program = new SingleThreaded();
				}
				else if(item.equals("heavy Weight"))
				{
					program = new HeavyWeight(null, true, new ReentrantLock(), new Splits(3), new Vector<Thread>());
				}
				else if(item.equals("singleQuque"))
				{
					program = new QuqueBreadthFirst(true);
				}
				
				Result = program.solve(treeOne, treeTwo, solveOptionsCB.getSelectedIndex() + 1,Integer.valueOf(kFLD.getText()));
				
				Collections.sort(Result);
				
				String[] results = new String[Result.size()];
				int i = 0;
				
				for(searchTreeNode node:Result)
				{
					results[i] = " MAF With Cuts :" + node.getNumberOfCuts();
					i++;
				}
				
				ListModel contents = list.getModel();
				contents = new prefuse.data.query.ListModel(results);
				list.setModel(contents);
			}
		});
		
		JButton showTreeOneBTN = new JButton("Show Tree One");
		showTreeOneBTN.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JFrame dialog = new JFrame("Tree one");
				dialog.setContentPane(TreeDisplayer.treeVeiwer(treeOne));
				dialog.pack();
				dialog.setVisible(true);			    
			}
		});
		
		JButton showTreeTwoBTN = new JButton("Show Tree Two");
		showTreeTwoBTN.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JFrame dialog = new JFrame("tree Two");
				dialog.setContentPane(TreeDisplayer.treeVeiwer(treeTwo));
				dialog.pack();
				dialog.setVisible(true);			    
			}
		});
		
		// set up the input panel
		input.setLayout(new GridLayout(0,5));
		
		input.add(new JLabel("Tree One : ", JLabel.CENTER));
		input.add(treeOneFLD);
		input.add(loadTreeOneBTN);
		input.add(saveTreeOneBtn);
		input.add(showTreeOneBTN);
		
		input.add(new JLabel("Tree Two : ", JLabel.CENTER));
		input.add(treeTwoFLD);
		input.add(loadTreeTwoBTN);
		input.add(saveTreeTwoBtn);
		input.add(showTreeTwoBTN);
		
		input.add(new JLabel("TBR : ", JLabel.CENTER));
		input.add(TBRFLD);
		input.add(mutateTreeBTN);
		input.add(new JLabel(""));
		input.add(new JLabel(""));
		
		input.add(new JLabel("Tree Size : ", JLabel.CENTER));
		input.add(treeSizeFLD);
		input.add(randomTreeBTN);
		input.add(new JLabel(""));
		
		input.add(new JLabel(""));
		input.add(new JLabel(""));
		input.add(new JLabel(""));
		input.add(new JLabel(""));
		input.add(new JLabel(""));
		
		input.add(new JLabel(""));
		input.add(findMAFBTN);
		input.add(ConcurrencyOptionsCB);
		input.add(solveOptionsCB);
		input.add(new JLabel("K value: "));
		input.add(kFLD);
		
		center.add(input,JSplitPane.LEFT);
//		center.add(soultions,JSplitPane.RIGHT);
		
//		final ArrayList<searchTreeNode> Result = coreAlgorithimTwo.run(new phylogeneticTree(10), new phylogeneticTree(10),coreAlgorithimTwo.ALL);
//		Collections.sort(Result);
//		
//		String[] results = new String[Result.size()];
//		int i = 0;
//		
//		for(searchTreeNode node:Result)
//		{
//			results[i] = " MAF With Cuts :" + node.getNumberOfCuts();
//			i++;
//		}
		
		
//		list = new JList(results); //data has type Object[]
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		list.setLayoutOrientation(JList.VERTICAL);
		list.setVisibleRowCount(-1);
		
		JScrollPane listScroller = new JScrollPane(list);
		listScroller.setPreferredSize(new Dimension(200, 500));
		
		JPanel listButtons = new JPanel();
		
		JButton showTree = new JButton("Show Selected MAF");
		showTree.addActionListener(new ActionListener() {			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int index = list.getSelectedIndex();
				JFrame dialog = new JFrame("Maximum Agreement Forest");
				dialog.setContentPane(TreeDisplayer.treeVeiwer(Result.get(index).getTree()));
				dialog.pack();
				dialog.setVisible(true);			    
			}
		});
		
		// MAF Buttons will be used as a part of results section 
		JButton saveMAFBTN = new JButton("Save Selected MAF");
		saveMAFBTN.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnVal = fc.showSaveDialog(new JPanel());
				int index = list.getSelectedIndex();
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = fc.getSelectedFile();
		            writeFile(Result.get(index).getTree().toCommaSeperatedFile(),file);
				}
			}
		});
		
		listButtons.add(showTree);
		listButtons.add(saveMAFBTN);	
		
		soultions.add(listScroller);
		soultions.add(listButtons);
		
		center.add(soultions,JSplitPane.RIGHT);
		
		
		page.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		page.setContentPane(center);
		page.setSize(1200, 600);
		page.setVisible(true);
	}
	
	private void writeFile(String serilizedTree,File file)
	{
		FileWriter fstream;
		try 
		{
			fstream = new FileWriter(file);
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(serilizedTree);
			out.close();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
}
